
from Base import *
from Header import *


class CStringItem(CItem):
    '''String item:
      This item include a header which indicates string length
      and a string
      its structure is similar like CInfoElement''' 
    _gName = "String Item"
    _gNameHeader = "Header"
    _gNameHex = "Hex"
    _gNameChar = "Char"

    def __init__(self,name=_gName, maxLen=-1):
        super(CStringItem, self).__init__(name)
        self._maxLen = maxLen

    def InitSubItem(self):
        name = self._gNameHeader
        item = CEleHeader(name)
        self._subList[name] = item
        self._nameList.append(name)

        name = self._gNameHex
        item = CItem(name)
        self._subList[name] = item
        self._nameList.append(name)

        name = self._gNameChar
        item = CItem(name)
        item.SetHighLighter(self._highLighter)
        item.SetColor('String')
        self._subList[name] = item
        self._nameList.append(name)

    def Parse(self, dataStr):
        #first initialize the sub item list
        self.InitSubItem()

        self._startIndex = dataStr.GetIndex()
        header = self._subList[self._gNameHeader]
        header.Parse(dataStr)

        len = header.GetLength()
        hLen = header.GetHeaderLength()

        if self._maxLen != -1:
            #this means set max len, so we should check it
            if len > self._maxLen:
                header._errStr = "Invalid length"

        string = dataStr.GetString(self._startIndex + hLen, self._startIndex + hLen + len)
        item = self._subList[self._gNameHex]
        item._rawStr = DATA_STRING_FORMAT.format(string)


        item = self._subList[self._gNameChar]
        cStr = ''
        for i in range(0,len):
            cStr = cStr + ("%c" % dataStr.GetByte())
        item._rawStr = "<" + STRING_FORMAT.format(cStr) + ">"


        #the raw data should include whole element string
        self._rawStr = DATA_STRING_FORMAT.format(dataStr.GetString(self._startIndex, self._startIndex + hLen + len))

        #end of parse()

class CVdFlag1(CItem):
    _gName = "vdFlag_1"
    _gNameVdf1AddFlag = "AddFlag"
    _gNameVdf1Language = "Language"
    _gNameVdf1Vin = "VIN"
    _gNameVdf1DcmId = "DCM_ID"
    _gNameVdf1NaviId = "NAVI_ID"
    _gNameVdf1ColModel = "Vehicle Color Model"
    _gNameVdf1Imei = "IMEI"

    _gAddFlag		= 0x80
    _gLanguageFlag	= 0x40
    _gVINFlag		= 0x20
    _gDCMFlag		= 0x10
    _gNaviFlag      = 0x08
    _gColoModelFlag = 0x06
    _gImeiFlag      = 0x01
    def __init__(self, name=_gName):
        super(CVdFlag1, self).__init__(name)
        self._vdFlag1 = 0
    
    def IsFlag2Present(self):
        return (self._vdFlag1 & self._gAddFlag) != 0

    def IsLanguagePresent(self):
        return (self._vdFlag1 & self._gLanguageFlag) != 0

    def IsVinPresent(self):
        return (self._vdFlag1 & self._gVINFlag) != 0

    def IsDcmIdPresent(self):
        return (self._vdFlag1 & self._gDCMFlag) != 0

    def IsNaviIdPresent(self):
        return (self._vdFlag1 & self._gNaviFlag) != 0

    def IsColoModelPresent(self):
        return (self._vdFlag1 & self._gColoModelFlag) != 0

    def IsImeiPresent(self):
        return (self._vdFlag1 & self._gImeiFlag) != 0

    def InitSubItem(self):
        name = self._gNameVdf1AddFlag
        self._subList[name] = CItem(name)
        self._nameList.append(name)

        name = self._gNameVdf1Language
        self._subList[name] = CItem(name)
        self._nameList.append(name)

        name = self._gNameVdf1Vin
        self._subList[name] = CItem(name)
        self._nameList.append(name)

        name = self._gNameVdf1DcmId
        self._subList[name] = CItem(name)
        self._nameList.append(name)

        name = self._gNameVdf1NaviId
        self._subList[name] = CItem(name)
        self._nameList.append(name)

        name = self._gNameVdf1ColModel
        self._subList[name] = CItem(name)
        self._nameList.append(name)

        name = self._gNameVdf1Imei
        self._subList[name] = CItem(name)
        self._nameList.append(name)

    def Parse(self, vdFlag):
        self.InitSubItem()

        self._vdFlag1 = vdFlag
        self._rawStr = HEX_DATA_FORMAT.format(vdFlag)

        item = self._subList[self._gNameVdf1AddFlag]
        if self.IsFlag2Present():
            f = 1
        else:
            f = 0
            item._errStr = "Invalid value"
        item._rawStr = DATA_FORMAT.format(f)

        item = self._subList[self._gNameVdf1Language]
        if self.IsLanguagePresent():
            f = 1
            item._errStr = "Invalid value"
        else:
            f = 0
        item._rawStr = DATA_FORMAT.format(f)

        item = self._subList[self._gNameVdf1Vin]
        if self.IsVinPresent():
            f = 1
            item._infoStr = "Present"
        else:
            f = 0
            item._infoStr = "Not Present"
        item._rawStr = DATA_FORMAT.format(f)

        item = self._subList[self._gNameVdf1DcmId]
        if self.IsDcmIdPresent():
            f = 1
            item._infoStr = "Present"
        else:
            f = 0
            item._infoStr = "Not Present"
        item._rawStr = DATA_FORMAT.format(f)

        item = self._subList[self._gNameVdf1NaviId]
        if self.IsNaviIdPresent():
            f = 1
            item._infoStr = "Present"
        else:
            f = 0
            item._infoStr = "Not Present"
        item._rawStr = DATA_FORMAT.format(f)

        item = self._subList[self._gNameVdf1ColModel]
        if self.IsColoModelPresent():
            f = 1
            item._errStr = "Invalid value"
        else:
            f = 0
        item._rawStr = DATA_FORMAT.format(f)

        item = self._subList[self._gNameVdf1Imei]
        if self.IsImeiPresent():
            f = 1
            item._errStr = "Invalid value"
        else:
            f = 0
        item._rawStr = DATA_FORMAT.format(f)

class CVdFlag2(CItem):
    _gName = "vdFlag_2"
    _gNameVdf2AddFlag = "AddFlag"
    _gNameVdf2ModelYear = "Model Year"
    _gNameVdf2AuthKey = "Authentication Key"
    _gNameVdf2IccId = "ICCID"
    _gNameVdf2Reserve = "Reserve"

    _gAddFlag		= 0x80
    _gYearFlag      = 0x40
    _gAuthKeyFlag   = 0x20
    _gIccidFlag     = 0x10
    _gReserveFlag   = 0x0F

    def __init__(self, name=_gName):
        super(CVdFlag2, self).__init__(name)
        self._vdFlag2 = 0

    def IsYearPresent(self):
        return (self._vdFlag2 & self._gYearFlag) != 0
    
    def IsAuthKeyPresent(self):
        return (self._vdFlag2 & self._gAuthKeyFlag) != 0
    
    def IsICCIdPresent(self):
        return (self._vdFlag2 & self._gIccidFlag) != 0

    def InitSubItem(self):
        name = self._gNameVdf2AddFlag
        self._subList[name] = CItem(name)
        self._nameList.append(name)

        name = self._gNameVdf2ModelYear
        self._subList[name] = CItem(name)
        self._nameList.append(name)

        name = self._gNameVdf2AuthKey
        self._subList[name] = CItem(name)
        self._nameList.append(name)

        name = self._gNameVdf2IccId
        self._subList[name] = CItem(name)
        self._nameList.append(name)

        name = self._gNameVdf2Reserve
        self._subList[name] = CItem(name)
        self._nameList.append(name)

    def Parse(self, vdFlag):
        self.InitSubItem()

        self._vdFlag2 = vdFlag
        self._rawStr = HEX_DATA_FORMAT.format(vdFlag)

        item = self._subList[self._gNameVdf2AddFlag]
        if ((self._vdFlag2 & self._gAddFlag) != 0):
            f = 1
            item._errStr= "Invalid value"
        else:
            f = 0
        item._rawStr = DATA_FORMAT.format(f)

        item = self._subList[self._gNameVdf2ModelYear]
        if self.IsYearPresent():
            f = 1
            item._errStr = "Invalid value"
        else:
            f = 0
        item._rawStr = DATA_FORMAT.format(f)

        item = self._subList[self._gNameVdf2AuthKey]
        if self.IsAuthKeyPresent():
            f = 1
            item._errStr = "Invalid value"
        else:
            f = 0
        item._rawStr = DATA_FORMAT.format(f)

        item = self._subList[self._gNameVdf2IccId]
        if self.IsICCIdPresent():
            f = 1
            item._infoStr = "Present"
        else:
            f = 0
            item._infoStr = "Not Present"
        item._rawStr = DATA_FORMAT.format(f)

        item = self._subList[self._gNameVdf2Reserve]
        if ((self._vdFlag2 & self._gReserveFlag) != 0):
            f = 1
            item._errStr= "Invalid value"
        else:
            f = 0
        item._rawStr = DATA_FORMAT.format(f)


class CVehicleDescriptorElement(CInfoElement):
    _gName = "Vehicle Descriptor"
    _gNameVdFlag1 = "vdFlag_1"

    _gNameVdFlag2 = "vdFlag_2"

    _gNameVin = "VIN"
    _gNameDcmId = "DCM ID"
    _gNameNaviId = "NAVI ID"
    _gNameIccId = "ICC ID"


    def __init__(self,name = _gName):
        super(CVehicleDescriptorElement, self).__init__(name)
        self._vdFlag1=0
        self._vdFlag2=0
        self._hlColor = 'black_on_white'


    def InitSubItem(self):
        name = self._gNameHeader
        item = CEleHeader(name)
        item.SetHighLighter(self._highLighter)
        item.SetColor('black_on_white')
        self._subList[name] = item
        self._nameList.append(name)

        name = self._gNameVdFlag1
        item = CVdFlag1(name)
        item.SetHighLighter(self._highLighter)
        item.SetColor('red_on_white')
        self._subList[name] = item
        self._nameList.append(name)
    
        name = self._gNameVdFlag2
        item = CVdFlag2(name)
        item.SetHighLighter(self._highLighter)
        item.SetColor('magenta_on_white')
        self._subList[name] = item
        self._nameList.append(name)
    
        name = self._gNameVin
        item = CStringItem(name)
        item.SetHighLighter(self._highLighter)
        item.SetColor('blue_on_white')
        self._subList[name] = item
        self._nameList.append(name)
    
        name = self._gNameDcmId
        item = CStringItem(name)
        item.SetHighLighter(self._highLighter)
        item.SetColor('black_on_white')
        self._subList[name] = item
        self._nameList.append(name)
    
        name = self._gNameNaviId
        item = CStringItem(name)
        item.SetHighLighter(self._highLighter)
        item.SetColor('darkgreen_on_white')
        self._subList[name] = item
        self._nameList.append(name)
    
        name = self._gNameIccId
        item = CStringItem(name)
        item.SetHighLighter(self._highLighter)
        item.SetColor('brown_on_white')
        self._subList[name] = item
        self._nameList.append(name)
    


        
    def ParseElement(self, dataStr):
        self._vdFlag1 = dataStr.GetByte()
        vdFlag1Item = self._subList[self._gNameVdFlag1]
        vdFlag1Item.Parse(self._vdFlag1)
        

        vdFlag2Item = self._subList[self._gNameVdFlag2]
        if vdFlag1Item.IsFlag2Present():
            self._vdFlag2 = dataStr.GetByte()
            vdFlag2Item.Parse(self._vdFlag2)

        name = self._gNameVin
        item = self._subList[name]
        if vdFlag1Item.IsVinPresent():
            item.Parse(dataStr)
        else:
            del self._subList[name]
            self._nameList.remove(name)

        name = self._gNameDcmId
        item = self._subList[name]
        if vdFlag1Item.IsDcmIdPresent():
            item.Parse(dataStr)
        else:
            del self._subList[name]
            self._nameList.remove(name)

        name = self._gNameNaviId
        item = self._subList[name]
        if vdFlag1Item.IsNaviIdPresent():
            item.Parse(dataStr)
        else:
            del self._subList[name]
            self._nameList.remove(name)

        name = self._gNameIccId
        item = self._subList[name]
        if vdFlag2Item.IsICCIdPresent():
            item.Parse(dataStr)
        else:
            del self._subList[name]
            self._nameList.remove(name)

